package example.client;



import java.util.Date;
import java.util.List;
import java.util.Scanner;

import com.google.inject.Guice;
import com.google.inject.Injector;

import example.dao.IFactoryDAO;
import example.dbutility.DBUtility;
import example.guice.IBatisModule;
import example.guice.OpenJPAModule;
import example.model.Account;

public class MainConsole {

	private static IFactoryDAO factoryDAO;
	
	public static void main(String args[]) {
		initDb();
		
		chooseFactory();
		
		accountManager();
		
	}
	
	
	public static void initDb() {
		DBUtility.initDerbyDb();
	}
	
	
	public static void accountManager() {		

		System.out.println("*********************************************************************");
		System.out.println("*********************************************************************");
		System.out.println("Welcome to the Account Manager Application, you are using: "+factoryDAO);

		boolean isExitMode = false;

		
		while (!isExitMode) {
			System.out.println("\n\nSelect one of the following operation:");
			System.out.println("Digit 1 to Create an account");
			System.out.println("Digit 2 to Retrieve an account");
			System.out.println("Digit 3 to Update an account");
			System.out.println("Digit 4 to Delete an account");
			System.out.println("Digit 5 to Show the account table");
			System.out.println("Digit 6 to EXIT");
			System.out.print("Which operation would you like perform? ");
			
			Scanner keyboard = new Scanner(System.in);
			int option = keyboard.nextInt();
			
			switch (option) {
				 case 1: {
				    createAccount();
				    break;
				 }
		         case 2: {
		            retrieveAccount();
		            break;
		         }
		         case 3: {
		            updateAccount();
		            break;
		         }
		         case 4: {
		             deleteAccount();
		             break;
		         }
		         case 5: {
		             showAccounts();
		             break;
		         }
		         default: {
		        	 isExitMode = true;
		         }
			}// end switch 
		}
		
		System.out.println("\n************************* APPLICATION END ***************************");
		System.out.println("*********************************************************************");

	}
	
//    accno VARCHAR(36) NOT NULL,
//    owner VARCHAR(36) NOT NULL,
//    date_open TIMESTAMP NOT NULL,
//	balance INT NOT NULL,
//    account_type VARCHAR(36) NOT NULL,
//	active SMALLINT DEFAULT 0 NOT NULL
	
	public static void createAccount(){
		System.out.println("\n-CREATE ACCOUNT-");
		String accno;
		String owner;
		int balance;
		String accountType;
		
		Scanner keyboard = new Scanner(System.in);
		
		System.out.print("Insert the account number to create (string): ");
		accno = keyboard.next();		
		
		System.out.print("Insert the account holder name (string): ");
		owner = keyboard.next();
		
		System.out.print("Insert the balance (numeric): ");
		balance = keyboard.nextInt();
		
		System.out.print("Insert the account description (string): ");
		accountType = keyboard.next();
		
		Account account = new Account();
		account.setAccno(accno);
		account.setAccountType(accountType);
		account.setOwner(owner);
		account.setBalance(balance);
		account.setDateOpen(new Date());
		account.setActive(true);
		
		
		
		try {
			factoryDAO.startTrasaction();
			factoryDAO.getAccountDao().create(account);
			factoryDAO.commitTransaction();
		}
		catch (Exception e) {
			e.printStackTrace();
			factoryDAO.roolbackTransaction();
		}
		
		
		
		
	}
	
	public static void retrieveAccount(){
		System.out.println("\n-RETRIVE ACCOUNT-");
		String accno;
		Scanner keyboard = new Scanner(System.in);
		
		System.out.print("Insert the account number to retrive it (string): ");
		accno = keyboard.next();
		
		try {
			factoryDAO.startTrasaction();
			Account account = factoryDAO.getAccountDao().retrieve(accno);
			factoryDAO.commitTransaction();
			
			System.out.print("This is the retrieved account: "+account);
		}
		catch (Exception e) {
			e.printStackTrace();
			factoryDAO.roolbackTransaction();
		}
		
	}
	
	public static void updateAccount(){
		System.out.println("\n-UPDATE ACCOUNT-");
		String accno;
		String owner;
		int balance;
		String accountType;
		boolean accountStatus;
		
		Scanner keyboard = new Scanner(System.in);
		
		System.out.print("Insert the account number to update (string): ");
		accno = keyboard.next();		
		
		System.out.print("Insert the new account holder name (string) (press enter if you don't want change it): ");
		owner = keyboard.next();
		
		System.out.print("Insert the new balance (numeric) (press enter if you don't want change it): ");
		balance = keyboard.nextInt();
		
		System.out.print("Insert the new account description (string) (press enter if you don't want change it): ");
		accountType = keyboard.next();
		
		System.out.print("Insert the new account status: (true or false): ");
		accountStatus = keyboard.nextBoolean();
		

		
		
		
		try {
			factoryDAO.startTrasaction();
			Account account = factoryDAO.getAccountDao().retrieve(accno);
			
			if (accountType!=null && accountType.trim().length()>0)
				account.setAccountType(accountType);
			if (owner!=null && owner.trim().length()>0)
				account.setOwner(owner);
			if (balance>0)
				account.setBalance(balance);
			
			account.setActive(accountStatus);
			
			factoryDAO.getAccountDao().update(account);
	
			factoryDAO.commitTransaction();
		}
		catch (Exception e) {
			e.printStackTrace();
			factoryDAO.roolbackTransaction();
		}
		
	}
	
	public static void deleteAccount(){
		System.out.println("\n-DELETE ACCOUNT-");
		String accno;
		Scanner keyboard = new Scanner(System.in);
		
		System.out.print("Insert the account number to remove it (string): ");
		accno = keyboard.next();
		
		try {
			factoryDAO.startTrasaction();
			factoryDAO.getAccountDao().remove(accno);
			factoryDAO.commitTransaction();
		}
		catch (Exception e) {
			e.printStackTrace();
			factoryDAO.roolbackTransaction();
		}
		
	}
	
	public static void showAccounts(){
		System.out.println("\n-SHOW ACCOUNTS-");
		
		try {
			factoryDAO.startTrasaction();
			List<Account> accounts = factoryDAO.getAccountDao().selectAll();
			factoryDAO.commitTransaction();
			
			for (Account a: accounts) {
				System.out.println("* "+a+" *");
			}
			
		}
		catch (Exception e) {
			// TODO: handle exception
			factoryDAO.roolbackTransaction();
		}
		
	}
	

	
	
	public static void chooseFactory() {
		
		Injector injector = null;
		
		System.out.println("*********************************************************************");
		System.out.println("*********************************************************************");
		System.out.println("Welcome to the Account Manager Application, please choose the Factory: ");
		System.out.println("Digit 1 to use a JPA DAO implementation");
		System.out.println("Digit 2 to use an Ibatis DAO implementation");
		System.out.println();	
		System.out.print("Which factory would you like use? ");
		
		Scanner keyboard = new Scanner(System.in);
		int option = keyboard.nextInt();
		
		if (option==1) {
			//factoryDAO = FactoryJPADao.getInstance();
			injector = Guice.createInjector(new OpenJPAModule());
			System.out.println("You are using a JPA DAO implementation.. ");
		}
		if (option==2) {
			//factoryDAO = FactoryIbatisDAO.getInstance();
			injector = Guice.createInjector(new IBatisModule());
			System.out.println("You are using an Ibatis DAO implementation... ");
		}
		
		factoryDAO = injector.getInstance(IFactoryDAO.class);
		
		System.out.println("*********************************************************************");
		System.out.println("*********************************************************************");

	}
	
	
}
